package com.weed.table;


import com.weed.table.Column.TableColumnEx;

import java.awt.*;

import javax.swing.*;
import javax.swing.UIDefaults.*;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

import java.util.Vector;

import com.weed.table.rowhead.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.text.Format;

import java.util.HashMap;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

/**
 * <ul>特性：
 * 函数说明：
 *<li>1）、列隐藏</li>
 *<li>2）、列排序(JDK已支持)</li>
 *<li>3）、行头显示</li>
 *<li>4）、多列头</li>
 *<li>5)、自动化最佳宽度</li>
 *<li>6）、打印</li>
 *<li>7）、打印浏览</li>
 *<li>8）、导出</li>
 *<li>9)、行编辑</li>
 *<li>11）、表格搜索</li>
 *<li>12）、格式化列</li>
 *<li>14）、保存样式</li>
 *<li>15）、行渐变</li>
 *<li>16）、锁定列</li>
 * </ul>
 *  作者     日期      说明
 *  卓志成   20080119  整理以前开发的BaseTable.
 */
public class BaseTable extends JTable 
        implements KeyListener {
    //行头是否显示
    protected boolean rowHeadVisible = true;
    //冻结前几列，目前处理关闭状态。
    protected int fixupColumn = -1;
    //行头组件。
    protected RowHeadComponent rowHeader = new RowHeadComponent(this);
    protected JViewport rowHead,  centerHead;
    //存储类格式化。
    protected HashMap columnFormatter = new HashMap();
    //用于存储待隐藏的列。
    protected HashMap columnVisableMap = new HashMap();
    
    //设置隐藏的列，使用逗号(,)融开。
    

    private boolean retValue;
    
    public BaseTable() {
        super();
        init();
    }
    
    

    public BaseTable(int row, int col) {
        super(row, col);
        init();
    }

    /**
     * 构造函数2.
     * @see JTable
     */
    public BaseTable(TableModel dm) {
        super(dm);
        init();
    }

    /**
     * 构造函数3
     *@see JTable
     */
    public BaseTable(TableModel dm, TableColumnModel cm) {
        super(dm, cm);
        init();
    }

    /**
     * 构造函数4
     *@see JTable
     */
    public BaseTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {
        super(dm, cm, sm);
        init();
    }

    /**
     * 构造函数6.
     *@see JTable
     */
    public BaseTable(Vector rowData, Vector columnNames) {
        super(rowData, columnNames);
        init();
    }

    /**
     * 构造函数7.
     *@see JTable
     */
    public BaseTable(Object[][] rowdata, Object[] columnNames) {
        super(rowdata, columnNames);
        init();
    }
    /**
     * 初始化。
     */
    protected void init() {
//        KeyStroke down = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
//        KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
//        ActionListener action_down = getActionForKeyStroke(down);
//        selectNextColumnCell
//        this.registerKeyboardAction(action_down,"selectNextColumn",enter, 0);//将回车键的事件改成向下的事件，实现回车时直接跳到下一单元格。
        this.setSurrendersFocusOnKeystroke(true);//设置获得焦点时，按键后单元格有光标。
        this.setAutoCreateRowSorter(true);//设置行自动排序。
//        this.addKeyListener(this);//编辑时清除数据。
        this.getTableHeader().addMouseListener(new MouseAdapter(){
            @Override
            public void mouseClicked(MouseEvent e) {}
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {rowHeader.repaint();}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
            @Override
            public void mouseWheelMoved(MouseWheelEvent e){}
            @Override
            public void mouseDragged(MouseEvent e){}
            @Override
            public void mouseMoved(MouseEvent e){}});
           //this.getTableHeader().setPreferredSize(new Dimension(0,28));
        setRowHeight(28);
    }
    public boolean getColumnVisable(int column){
        Object ret = columnVisableMap.get(column);
        if( ret == null)
            return true;
        return (Boolean)ret;
    }
    public void setColumnVisable(String column,boolean visabled){
        if(column == null || column.equals(""))return ;
        TableColumn tc = this.getColumn(column);
        TableModel tm = this.getModel();
        if(tc!=null){
            if(tc instanceof TableColumnEx)
                ((TableColumnEx)tc).setVisible(visabled);
            columnVisableMap.put(column, visabled);
        }
        if(tm!=null && tm instanceof AbstractTableModel)
            ((AbstractTableModel)tm).fireTableDataChanged();
            
    }
   public void createDefaultColumnsFromModel()  {
        TableModel m = getModel();
        if (m != null) {
            // Remove any current columns
            TableColumnModel cm = getColumnModel();
            while (cm.getColumnCount() > 0) {
                cm.removeColumn(cm.getColumn(0));
	    }
            // Create new columns from the data model info
            for (int i = 0; i < m.getColumnCount(); i++) { 
                TableColumnEx newColumn = new TableColumnEx(i);
                //TableColumn newColumn = new TableColumn(i);  
                addColumn(newColumn);
            }
        }
    }

    /**获得行头是否显示。*/
    public boolean isRowHeadVisible() {
        return rowHeadVisible;
    }

    /**设置行头是否显示。*/
    public void setRowHeadVisible(boolean rowHeadVisible) {
        this.rowHeadVisible = rowHeadVisible;
    }

    /**设置指定列的大小。*/
    public void fixupColumn(int count) {
        rowHeader.fixuped(count);
    }

    /**当行头发生改变时，用于处理行头的显示。*/
    public void configureEnclosingScrollPane() {
        super.configureEnclosingScrollPane(); //只显示行头。
        if(rowHeader !=null)
         rowHeader.fixuped(0);
        Container p = getParent();
        if (p != null && p instanceof JViewport) {
            centerHead = (JViewport) p;
            p = p.getParent();
            if (p != null && p instanceof JScrollPane) {
                JScrollPane sp = (JScrollPane) p;
                rowHead = sp.getRowHeader();
                rowHead.addChangeListener(new RowHeadChangeHandler(centerHead));
                rowHead.setVisible(rowHeadVisible);
            }
        }
    }

    /**
     * 获得固定的行数。
     * @return int 行数。
     */
    public int getFixupColumn() {
        return fixupColumn;
    }

    /**
     * 设置固定的行数。
     * @param fixupColumn int
     */
    public void setFixupColumn(int fixupColumn) {
        this.fixupColumn = fixupColumn;
    }

    /**
     * 设置列的格式化。
     * @param columnName
     * @param format
     */
    public void setColumnFormatter(int column, Format format) {
        this.columnFormatter.put(String.valueOf(column), format);
    }

    /**
     * 设置列的格式化。
     * @param columnName
     * @return
     */
    public Format getColumnFormatter(int column) {
        return (Format) columnFormatter.get(String.valueOf(column));
    }
    public void keyReleased(KeyEvent e) {}
    public void keyTyped(KeyEvent e) {}
    public void keyPressed(KeyEvent e) {
        JTable t = (JTable) e.getSource();
        int row = t.getSelectedRow();
        int col = t.getSelectedColumn();
        //下面程序触发开始编辑，然后全选编辑器的文本
        t.editCellAt(row, col);
        JTextField editor = (JTextField) t.getCellEditor().getTableCellEditorComponent(t, t.getValueAt(row, col), true, row, col);
        editor.selectAll();
    }
   /****************************************************************
    * 新增接口。
    * 
    * 
    **************************************************************/
    
   /**
     * 自动化的列大小，也是理想的列大不。
     */ 
    public void adjustColumnPreferredWidths() {
        // strategy - get max width for cells in column and
        // make that the preferred width
        TableColumnModel columnModel = this.getColumnModel();
        for (int col = 0; col < this.getColumnCount(); col++) {
            int maxwidth = 0;
            for (int row = 0; row < this.getRowCount(); row++) {
                TableCellRenderer rend =
                        this.getCellRenderer(row, col);
                Object value = this.getValueAt(row, col);
                Component comp =
                        rend.getTableCellRendererComponent(this,
                        value,
                        false,
                        false,
                        row,
                        col);
                if(comp.getPreferredSize().width <1000)
                maxwidth = Math.max(comp.getPreferredSize().width, maxwidth);
            } // for row
            TableColumn column = columnModel.getColumn(col);
            TableCellRenderer headerRenderer = column.getHeaderRenderer();
            if (headerRenderer == null) {
                headerRenderer = this.getTableHeader().getDefaultRenderer();
            }
            Object headerValue = column.getHeaderValue();
            Component headerComp =
                    headerRenderer.getTableCellRendererComponent(this,
                    headerValue,
                    false,
                    false,
                    0,
                    col);
           maxwidth = Math.max(maxwidth+10,
                    headerComp.getPreferredSize().width+25);
          if(maxwidth <1000)
            column.setPreferredWidth(maxwidth);
        } // for col 
    }

   

    
}
